<div>

</div>

<template>
  <style>
    :host {
      display: block;
      user-select: none;
      position: relative
    }

    :host::before {
      content: '';
      height: 100%;
      width: 100%;
      position: absolute;
      opacity: 0;
      transition: opacity .2s;
      border-radius: inherit;
      pointer-events: none;
      background: var(--color-ripple);
      left: 0;
      top: 0
    }

    @keyframes ripple {
      0% {
        opacity: 0
      }

      100% {
        opacity: 1
      }
    }

    .ripple,
    .ripple::before {
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      position: absolute;
      pointer-events: none
    }

    .ripple {
      display: flex;
      justify-content: center;
      align-items: center;
      overflow: hidden
    }

    .ripple::before {
      content: '';
      background: var(--color-ripple);
      opacity: 0
    }

    .ripple.show::before {
      animation: ripple 0s ease .2s;
      animation-fill-mode: forwards
    }

    @keyframes anime {
      0% {
        transform: translate(var(--x), var(--y)) scale(.2);
        opacity: 1
      }

      100% {
        transform: translate(0px, 0px) scale(1);
        opacity: 1
      }
    }

    .ripple>.anime {
      background: var(--color-ripple);
      border-radius: 50%;
      flex-shrink: 0;
      opacity: 0;
      will-change: transform
    }

    @media(pointer:fine) {
      :host(:hover)::before {
        opacity: .24
      }
    }
  </style>
  <div class="ripple" part="ripple">
    <div class="anime" part="anime"></div>
  </div>
  <slot></slot>
</template>
<script type="module">
  import { define } from '../../core.js'
  import { animationEnd } from '../../util.js'

  const template = $template

  const mouse = window.matchMedia('(pointer:fine)')
  let isMouse = mouse.matches
  mouse.addEventListener('change', ({ matches }) => (isMouse = matches))


  const setup = (shadow, node) => {
    const ripple = shadow.querySelector('.ripple')
    const anime = shadow.querySelector('.anime')

    let isDown = false

    const down = e => {
      if (e.button === 2) return
      const { pageX, pageY } = e
      const { left, top } = node.getBoundingClientRect()
      const { offsetWidth, offsetHeight } = node
      const float = { x: pageX - left, y: pageY - top }
      const diameter = Math.pow(Math.pow(offsetHeight, 2) + Math.pow(offsetWidth, 2), 0.5)
      const x = ((offsetWidth / 2) - float.x) / -1
      const y = ((offsetHeight / 2) - float.y) / -1
      animationEnd(anime, () => anime.removeAttribute('style'))
      anime.setAttribute('style', `width:${diameter}px;height:${diameter}px;--x:${x}px;--y:${y}px;animation:anime .2s`)
      ripple.classList.add('show')
      isDown = true
      node.setAttribute('active', 'active')
    }
    const up = () => {
      if (isDown === false) return
      ripple.classList.remove('show')
      isDown = false
      node.removeAttribute('active')
    }

    node.addEventListener('mousedown', e => isMouse && down(e))
    node.addEventListener('mouseup', () => isMouse && up())
    node.addEventListener('mouseleave', () => isMouse && up())

    node.addEventListener('touchstart', e => down(e.changedTouches[0]))
    node.addEventListener('touchend', up)
    node.addEventListener('touchcancel', up)
  }

  define('ripple', { template, setup })
</script>